

package model.db;

import java.sql.*;
import java.util.ArrayList;
import model.db.table.Table;

/**
 * Author: Raoux Etienne
 * Student login: jc218934
 * Student number: 12448190
 * email: etienne.raoux@my.jcu.edu.au
 * alt email: jc218934@gmail.com
 */
public class Execute
{
    private static ArrayList<String> stringsToExecute = new ArrayList<String>();
    private static boolean working = false;


    public static void execute (String stringToExecute)
    {
        stringsToExecute.add(stringToExecute);
        startExecuting();
    }

    private static void startExecuting()
    {
        if (working) return;
        working = true;
        while (!stringsToExecute.isEmpty())
        {
            String stringToExecute = stringsToExecute.get(0);
            stringsToExecute.remove(0);
            executeString(stringToExecute);
        }
        working = false;
    }

    private static void executeString(String stringToExecute)
    {
        try
        {
            Connection con = OurConnection.connect();
            Statement stmt = con.createStatement();
            System.out.println(stringToExecute);
            stmt.execute(stringToExecute);
            stmt.close(); // close the Statement
            con.close();
        }
        catch (Exception ex)
        {
            System.err.println("Execute "+ex);
        }
    }


    public static <T extends Table> ArrayList<T> returnValuesOf(String stringToExecute, T c)
    {
        ResultSet rs =null;
        ArrayList<T> rowList = new ArrayList<T>();
        try
        {
            rs = returnResultSet(stringToExecute);

            for (; rs.next();)
            {
                String [] columnNames = c.getColumnNames();
                Class [] columnTypes = c.getColumnTypes();
                int numParam = columnNames.length;
                Object [] columnValues = new Object [numParam];
                for (int i =0; i<numParam;++i)
                {
                    columnValues[i] = getValue(rs, columnNames[i], columnTypes[i]);
                }
                T t = (T) c.getClass().newInstance();
                t.initValues(columnValues);
                rowList.add(t);
            }
        }
        catch (Exception ex)
        {
            System.err.println("Execute returnValuesOf "+ex);
            return rowList;
        }
        if (rs == null)
        {
            return rowList;
        }
        return rowList;
    }

    private static Object getValue(ResultSet rs, String columnName, Class columnType)
    {
        try
        {
            if (columnType == Integer.class) return new Integer(rs.getInt(columnName));
            if (columnType == String.class) return rs.getString(columnName);
            if (columnType == Date.class) return rs.getDate(columnName);
            if (columnType == Time.class) return rs.getTime(columnName);
            if (columnType == Double.class) return new Double(rs.getDouble(columnName));
            System.err.println(columnType + "not supported yet(Execute)");
            return null;
        }
        catch (Exception ex)
        {
            return null;
        }
    }

    private static ResultSet returnResultSet (String statement) throws Exception
    {
        Connection con = OurConnection.connect();
        Statement stmt = con.createStatement();
        return stmt.executeQuery(statement);
    }

    public static <T extends Table> T returnValueOf(String stringToExecute, T c)
    {
        ResultSet rs =null;
        T t =null;
        try
        {
            rs = returnResultSet(stringToExecute);

            for (; rs.next();)
            {
                String [] columnNames = c.getColumnNames();
                Class [] columnTypes = c.getColumnTypes();
                int numParam = columnNames.length;
                Object [] columnValues = new Object [numParam];
                for (int i =0; i<numParam;++i)
                {
                    columnValues[i] = getValue(rs, columnNames[i], columnTypes[i]);
                }
                t = (T) c.getClass().newInstance();
                t.initValues(columnValues);
            }
        }
        catch (Exception ex)
        {
            System.err.println("Execute "+ex);
            return c;
        }
        if (rs == null)
        {
            return c;
        }
        return t;
    }

    public static <T extends Table> Integer returnNextIdOf(T c)
    {
        ResultSet rs =null;
        Integer id =0;
        try
        {
            System.out.println("SELECT MAX("+c.getPrimaryKeyNames()[0]+") FROM "+c.getTableNames()[0]);
            rs = returnResultSet("SELECT MAX("+c.getPrimaryKeyNames()[0]+") FROM "+c.getTableNames()[0]);

            for (; rs.next();)
            {
                id = rs.getInt(1);
            }
        }
        catch (Exception ex)
        {
            System.err.println("Execute "+ex);
        }
        return id+1;
    }

    public static ArrayList<String> returnStringValuesOf(String stringToExecute)
    {
        ResultSet rs =null;
        ArrayList<String> stringList = new ArrayList<String>();
        try
        {
            rs = returnResultSet(stringToExecute);

            for (; rs.next();)
            {
                stringList.add(rs.getString(1));
            }
        }
        catch (Exception ex)
        {
            System.err.println("Execute "+ex);
        }
        return stringList;
    }

    public static ArrayList<Date> returnScDateValuesOf(String stringToExecute)
    {
        ResultSet rs =null;
        ArrayList<Date> stringList = new ArrayList<Date>();
        try
        {
            rs = returnResultSet(stringToExecute);

            for (; rs.next();)
            {
                stringList.add(rs.getDate(1));
            }
        }
        catch (Exception ex)
        {
            System.err.println("Execute "+ex);
        }
        return stringList;
    }

    public static ArrayList<String> returnScDateAsStrValuesOf(String stringToExecute)
    {
        ResultSet rs =null;
        ArrayList<String> stringList = new ArrayList<String>();
        try
        {
            rs = returnResultSet(stringToExecute);

            for (; rs.next();)
            {
                stringList.add(rs.getDate(1).toString());
            }
        }
        catch (Exception ex)
        {
            System.err.println("Execute "+ex);
        }
        return stringList;
    }

    public static boolean checkIfValueExist(String stringToExecute)
    {
        ResultSet rs =null;
        try
        {
            System.out.println(stringToExecute);
            rs = returnResultSet(stringToExecute);

            for (; rs.next();)
            {
                System.out.println("found");
                return true;
            }
        }
        catch (Exception ex)
        {
            System.err.println("Execute "+ex);
        }
        return false;
    }
}

